In computer software systems, it may be desirable for applications to execute concurrently. However, it is also desirable to ensure that the applications do not concurrently perform conflicting operations, such as one application writing to a storage location while another application is reading from the storage location.
One particular instance in which it is desirable to ensure that concurrently executing applications do not conflict with each other occurs in software utilities that share access to a storage array. For example, one software utility that accesses a storage array, such as a redundant array of inexpensive disks (RAID) array, is an application, referred to as clones, that makes point in time copies of data stored in a location on a storage array. The clones application may make multiple point in time copies so that a user can go back to a previous version of data if new data is erroneously written over data that it is desirable to keep. The process of making a point in time copy of data on a storage array is referred to herein as cloning. The process of replacing a current copy with a previous point in time copy is referred to herein as reverse synching.
Another software utility that may access a storage array is referred to as the mirror view application. The mirror view application may copy data from a storage medium, such as a RAID array, to a remote storage medium, such as another RAID array, for disaster recovery purposes. The process of copying data to a remote RAID array is referred to as a synch operation.
One example of conflicting operations that may be performed by the clones application and the mirror view application is a synch operation and a reverse synch operation regarding the same data. These two operations conflict with each other because it is not desirable to mirror data from a source logical unit (LUN) when the reverse synch to the source LUN is partially complete due to data mismatches that can occur. A logical unit or LUN is a data structure that represents one or more data storage blocks in a disk array. The data in different blocks of a LUN may be logically related. For example, if the LUN is used to store payroll data, block one of a LUN may include a person's name, and block two may include the person's salary. During a reverse synch, the data in block one may be overwritten with another person's name from a previous point in time copy of the LUN. As a result, the data in block one does not match the data in block 2. It is desirable to prevent this data mismatch from being copied to the mirror LUN by a mirror view application.
One conventional method for avoiding such conflicts is to provide separate locks for the synch and reverse synch operations. For example, when a clones application initiates a reverse synch operation regarding stored data, the clones application may obtain a lock preventing other clones applications from initiating reverse synch operations regarding the data. The clones application may then attempt to obtain a second lock to prevent other mirror view applications from initiating synch operations regarding the data. If a mirror view application attempts to start a synch operation at the same time that the clones application is initiating a reverse synch, the mirror view application will first attempt to obtain the lock for locking other mirror view applications from performing synch operations regarding the data. If the clones application has not yet attempted to obtain this lock, the mirror view application will be successful in obtaining the mirror view lock. However, when the mirror view application attempts to obtain the clones lock, the mirror view application will be unsuccessful in obtaining the clones lock, because this lock has already been obtained by the clones application. Similarly, when the clones application attempts to obtain the mirror view lock, the clones application will be unsuccessful because this lock has already been obtained by the mirror view application. Since both the clones and mirror view applications are waiting for locks from the other applications, and the locks will not be released, a deadlock is created.
Another potential mechanism for avoiding conflicting operations while avoiding deadlocks is to provide a single common software lock for both software utilities. However, such a lock may not be available when one of the utilities operates in kernel space and the other operates in user space, as is the case with the above-referenced clones and mirror view applications.
Accordingly, in light of these difficulties, there exists a need for methods, systems, and computer program products for preventing concurrent execution of conflicting software operations on the same and different storage processors having access to a common storage medium while avoiding deadlocks.